package jst.btremote.gui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import yuku.ambilwarna.AmbilWarnaDialog;
import yuku.ambilwarna.AmbilWarnaDialog.OnAmbilWarnaListener;
import jst.btremote.R;
import jst.btremote.bluetooth.BluetoothCommunication;
import jst.btremote.bluetooth.BluetoothConnector;
import jst.btremote.bluetooth.CommandBuilder;
import android.app.ActionBar;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements ActionBar.OnNavigationListener {

	/**
	 * The serialization (saved instance state) Bundle key representing the
	 * current dropdown position.
	 */
	private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// Set up the action bar to show a dropdown list.
		final ActionBar actionBar = getActionBar();
		actionBar.setDisplayShowTitleEnabled(false);
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

		// Set up the dropdown list navigation in the action bar.
		actionBar.setListNavigationCallbacks(
		// Specify a SpinnerAdapter to populate the dropdown list.
				new ArrayAdapter<String>(actionBar.getThemedContext(), android.R.layout.simple_list_item_1, android.R.id.text1, new String[] {
						getString(R.string.title_bt_message), getString(R.string.title_bt_light), getString(R.string.title_bt_browser),
						getString(R.string.title_settings), }), this);
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		// Restore the previously serialized current dropdown position.
		if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
			getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		// Serialize the current dropdown position.
		outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onNavigationItemSelected(int position, long id) {
		Fragment fragment;
		Bundle args = new Bundle();
		switch (position) {
		case 0:
			// Send message via Bluetooth
			fragment = new SendMessageFragment();
			break;
		case 1:
			// Send message via Bluetooth
			fragment = new LightControlFragment();
			break;
		case 2:
			// Bluetooth Browser
			fragment = new BTBrowserFragment();
			break;
		default:
			fragment = new DummySectionFragment();
			args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
			break;
		}
		fragment.setArguments(args);
		getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).commit();
		return true;
	}

	/**
	 * A dummy fragment representing a section of the app, but that simply
	 * displays dummy text.
	 */
	public static class DummySectionFragment extends Fragment {
		/**
		 * The fragment argument representing the section number for this
		 * fragment.
		 */
		public static final String ARG_SECTION_NUMBER = "section_number";

		public DummySectionFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			final View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);

			return rootView;
		}
	}

	/**
	 * Send message via Bluetooth
	 * 
	 * @author jonassteffens
	 * 
	 */
	public static class SendMessageFragment extends Fragment {

		private ArrayList<BluetoothDevice> pairedDevices;
		private BluetoothConnector btConnector = null;

		public SendMessageFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			final View rootView = inflater.inflate(R.layout.frgmt_main_sendmessage, container, false);

			final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

			// fill paired devices
			Spinner spnDevice = (Spinner) rootView.findViewById(R.id.spn_device);
			this.pairedDevices = new ArrayList<BluetoothDevice>();
			List<String> spnDeviceList = new ArrayList<String>();

			Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
			if (pairedDevices.size() > 0) {
				for (BluetoothDevice device : pairedDevices) {
					this.pairedDevices.add(device);
					spnDeviceList.add(device.getName());
				}
			}
			spnDevice.setAdapter(new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_dropdown_item, spnDeviceList));
			spnDevice.setOnItemSelectedListener(new OnItemSelectedListener() {
				@Override
				public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
					if ((SendMessageFragment.this.btConnector != null) && (SendMessageFragment.this.btConnector.getBluetoothSocket() != null)) {
						try {
							SendMessageFragment.this.btConnector.getBluetoothSocket().close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
					SendMessageFragment.this.btConnector = new BluetoothConnector(SendMessageFragment.this.pairedDevices.get(((Spinner) rootView
							.findViewById(R.id.spn_device)).getSelectedItemPosition()), BluetoothAdapter.getDefaultAdapter());
				}

				@Override
				public void onNothingSelected(AdapterView<?> arg0) {
				}
			});

			Button btnSend = (Button) rootView.findViewById(R.id.btn_lightcontrol_send);
			btnSend.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					if (SendMessageFragment.this.btConnector != null) {
						// EditText edtMessage = (EditText)
						// rootView.findViewById(R.id.edt_message);
						// BluetoothCommunication btCommunication = new
						// BluetoothCommunication(SendMessageFragment.this.btConnector,
						// edtMessage
						// .getText().toString());
						// btCommunication.start();
					}
				}
			});
			return rootView;
		}

		@Override
		public void onDestroy() {
			if ((this.btConnector != null) && (this.btConnector.getBluetoothSocket() != null)) {
				try {
					this.btConnector.getBluetoothSocket().close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			super.onDestroy();
		}
	}

	/**
	 * Send message via Bluetooth
	 * 
	 * @author jonassteffens
	 * 
	 */
	public static class LightControlFragment extends Fragment {

		private ArrayList<BluetoothDevice> pairedDevices;
		private BluetoothCommunication btCommunication = null;
		private View rootView;

		Handler threadHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				try {
				Bundle bundle = msg.getData();
				Toast.makeText(LightControlFragment.this.getActivity(), bundle.getString("message"), Toast.LENGTH_SHORT).show();
				super.handleMessage(msg);
				} catch(NullPointerException e) {
					
				}
			}

		};

		public LightControlFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			this.rootView = inflater.inflate(R.layout.frgmt_main_lightcontrol, container, false);

			this.setupDeviceSpinner(rootView);

			this.setupSeekBars(rootView);
			
//			LightControlFragment.this.btCommunication = new BluetoothCommunication(LightControlFragment.this.pairedDevices.get(((Spinner) rootView
//					.findViewById(R.id.spn_device)).getSelectedItemPosition()), LightControlFragment.this.threadHandler);

			// Color picker
			Button btnColorPicker = (Button) rootView.findViewById(R.id.btn_colorpicker);
			btnColorPicker.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					AmbilWarnaDialog dialog = new AmbilWarnaDialog(rootView.getContext(), 0, new OnAmbilWarnaListener() {
						@Override
						public void onOk(AmbilWarnaDialog dialog, int color) {
							SeekBar seekBarRed = (SeekBar) rootView.findViewById(R.id.seekbar_red);
							SeekBar seekBarGreen = (SeekBar) rootView.findViewById(R.id.seekbar_green);
							SeekBar seekBarBlue = (SeekBar) rootView.findViewById(R.id.seekbar_blue);
							int blue = (int) (color & 0xFF);
							int green = (int) ((color >> 8) & 0xFF);
							int red = (int) ((color >> 16) & 0xFF);
							View colorPreView = (View) rootView.findViewById(R.id.color_preview);
							colorPreView.setBackgroundColor(color);
							seekBarRed.setProgress(red);
							seekBarGreen.setProgress(green);
							seekBarBlue.setProgress(blue);
							LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildRGBMessage(red, green, blue));
						}

						@Override
						public void onCancel(AmbilWarnaDialog dialog) {
							// cancel was selected by the user
						}
					});

					dialog.show();
				}
			});

			Button btnSend = (Button) rootView.findViewById(R.id.btn_lightcontrol_send);
			btnSend.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					int red = ((SeekBar) rootView.findViewById(R.id.seekbar_red)).getProgress();
					int green = ((SeekBar) rootView.findViewById(R.id.seekbar_green)).getProgress();
					int blue = ((SeekBar) rootView.findViewById(R.id.seekbar_blue)).getProgress();
					LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildRGBMessage(red, green, blue));
				}
			});

			Button btnStart = (Button) rootView.findViewById(R.id.btn_automatedLight_start);
			btnStart.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildAutoGradient(true));
				}
			});

			Button btnStop = (Button) rootView.findViewById(R.id.btn_automatedLight_stop);
			btnStop.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildAutoGradient(false));
				}
			});

			return rootView;
		}

		private void setupDeviceSpinner(final View rootView) {
			final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
			// fill paired devices
			Spinner spnDevice = (Spinner) rootView.findViewById(R.id.spn_device);
			this.pairedDevices = new ArrayList<BluetoothDevice>();
			List<String> spnDeviceList = new ArrayList<String>();

			Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
			if (pairedDevices.size() > 0) {
				for (BluetoothDevice device : pairedDevices) {
					this.pairedDevices.add(device);
					spnDeviceList.add(device.getName());
				}
			}
			spnDevice.setAdapter(new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_dropdown_item, spnDeviceList));
			spnDevice.setOnItemSelectedListener(new OnItemSelectedListener() {
				@Override
				public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
					// close old thread
					if (LightControlFragment.this.btCommunication != null) {
						LightControlFragment.this.btCommunication.endCommunication();
					}
					LightControlFragment.this.btCommunication = new BluetoothCommunication(LightControlFragment.this.pairedDevices
							.get(((Spinner) rootView.findViewById(R.id.spn_device)).getSelectedItemPosition()),
							LightControlFragment.this.threadHandler);
				}

				@Override
				public void onNothingSelected(AdapterView<?> arg0) {
				}
			});
		}

		private void setupSeekBars(final View rootView) {
			// Color Seek Bars
			SeekBar seekBarRed = (SeekBar) rootView.findViewById(R.id.seekbar_red);
			SeekBar seekBarGreen = (SeekBar) rootView.findViewById(R.id.seekbar_green);
			SeekBar seekBarBlue = (SeekBar) rootView.findViewById(R.id.seekbar_blue);

			seekBarRed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
				@Override
				public void onStopTrackingTouch(SeekBar seekBar) {
					LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildRedLEDMessage(seekBar.getProgress()));
				}

				@Override
				public void onStartTrackingTouch(SeekBar seekBar) {
				}

				@Override
				public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
					LightControlFragment.this.setSeekBarColorPreview(rootView);
				}
			});

			seekBarGreen.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
				@Override
				public void onStopTrackingTouch(SeekBar seekBar) {
					LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildGreenLEDMessage(seekBar.getProgress()));
				}

				@Override
				public void onStartTrackingTouch(SeekBar seekBar) {
				}

				@Override
				public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
					LightControlFragment.this.setSeekBarColorPreview(rootView);
				}
			});

			seekBarBlue.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
				@Override
				public void onStopTrackingTouch(SeekBar seekBar) {
					LightControlFragment.this.btCommunication.sendMessage(CommandBuilder.buildBlueLEDMessage(seekBar.getProgress()));
				}

				@Override
				public void onStartTrackingTouch(SeekBar seekBar) {
				}

				@Override
				public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
					LightControlFragment.this.setSeekBarColorPreview(rootView);
				}
			});
		}

		private void setSeekBarColorPreview(View rootView) {
			int red = ((SeekBar) rootView.findViewById(R.id.seekbar_red)).getProgress();
			int green = ((SeekBar) rootView.findViewById(R.id.seekbar_green)).getProgress();
			int blue = ((SeekBar) rootView.findViewById(R.id.seekbar_blue)).getProgress();
			View colorPreView = (View) rootView.findViewById(R.id.color_preview);
			int rgb = ((255 & 0x0ff) << 24) | ((red & 0x0ff) << 16) | ((green & 0x0ff) << 8) | (blue & 0x0ff);
			colorPreView.setBackgroundColor(rgb);
		}

		@Override
		public void onDestroy() {
			if (this.btCommunication != null) {
				this.btCommunication.endCommunication();
			}
			super.onDestroy();
		}

	}

	/**
	 * Bluetooth Browser
	 * 
	 * @author jonassteffens
	 * 
	 */
	public static class BTBrowserFragment extends Fragment {

		private BluetoothAdapter mBTA;
		private SingBroadcastReceiver mReceiver;
		private List<String> deviceList;
		private ListView listBtBrowser;

		public BTBrowserFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			final View rootView = inflater.inflate(R.layout.frgmt_main_bt_browser, container, false);

			Button btn_search = (Button) rootView.findViewById(R.id.btn_bt_browser_search);
			btn_search.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					reloadList(rootView);
				}
			});

			return rootView;
		}

		public void reloadList(View rootView) {
			listBtBrowser = (ListView) rootView.findViewById(R.id.lst_bt_browser);
			deviceList = new ArrayList<String>();

			// register local BT adapter
			mBTA = BluetoothAdapter.getDefaultAdapter();
			// check to see if there is BT on the Android device at all
			if (mBTA == null) {
				int duration = Toast.LENGTH_SHORT;
				Toast.makeText(this.getActivity(), "No Bluetooth on this handset", duration).show();
			}
			// let's make the user enable BT if it isn't already
			if (!mBTA.isEnabled()) {
				Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
				startActivityForResult(enableBT, 0);
			}
			// cancel any prior BT device discovery
			if (mBTA.isDiscovering()) {
				mBTA.cancelDiscovery();
			}
			// re-start discovery
			mBTA.startDiscovery();

			// let's make a broadcast receiver to register our things
			mReceiver = new SingBroadcastReceiver();
			IntentFilter ifilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
			this.getActivity().registerReceiver(mReceiver, ifilter);
		}

		private class SingBroadcastReceiver extends BroadcastReceiver {

			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction(); // may need to chain this to
													// a recognizing function
				if (BluetoothDevice.ACTION_FOUND.equals(action)) {
					// Get the BluetoothDevice object from the Intent
					BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
					// Add the name and address to an array adapter to show in a
					// Toast
					String derp = device.getName() + " - " + device.getAddress();
					deviceList.add(derp);
					listBtBrowser.setAdapter(new ArrayAdapter<String>(BTBrowserFragment.this.getActivity(), android.R.layout.simple_list_item_1,
							deviceList));
					System.out.println(derp);
				}
			}
		}

	}

}
